Skip to content

Add stop thread keybinding command#4308

Open
jakeleventhal wants to merge 1 commit into
pingdotgg:mainfrom
jakeleventhal:t3code/add-stop-thread-keybinding
Open

Add stop thread keybinding command#4308
jakeleventhal wants to merge 1 commit into
pingdotgg:mainfrom
jakeleventhal:t3code/add-stop-thread-keybinding

Conversation

@jakeleventhal

@jakeleventhal jakeleventhal commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Summary

Screen.Recording.2026-07-22.at.4.36.45.PM.mov
  • add a typed thread.stop keybinding command without assigning a default shortcut
  • expose all static commands, including unbound ones, in the keybinding picker
  • route the command through the focused thread's existing turn-interrupt behavior

Testing

  • vp test run packages/contracts/src/keybindings.test.ts apps/web/src/keybindings.test.ts apps/web/src/components/settings/KeybindingsSettings.logic.test.ts (58 tests)
  • vp run typecheck in packages/contracts
  • vp run typecheck in apps/web
  • targeted vp fmt --check and vp lint for all changed files
  • integrated browser verification with a real running Codex turn and a custom thread.stop binding; the turn returned to ready with no active turn or error

Note

Add thread.stop keybinding command to interrupt the active thread turn

  • Adds thread.stop to THREAD_KEYBINDING_COMMANDS in the contracts package and exports STATIC_KEYBINDING_COMMANDS for use by consumers.
  • Wires a keydown handler in ChatViewContent that invokes onInterrupt when the thread.stop command fires, surfacing failures via setThreadError.
  • Updates buildKeybindingCommandOptions to seed from STATIC_KEYBINDING_COMMANDS instead of DEFAULT_RESOLVED_KEYBINDINGS, ensuring thread.stop appears in the keybindings settings UI even though it has no default binding.

Macroscope summarized 7ae0496.


Note

Low Risk
Reuses existing turn-interrupt RPC and UI error handling; no default shortcut and no auth or data-model changes.

Overview
Adds a typed thread.stop keybinding command so users can stop the current agent turn from a custom shortcut (there is no default binding).

Contracts: thread.stop is included in THREAD_KEYBINDING_COMMANDS, and STATIC_KEYBINDING_COMMANDS is exported for the web app.

Chat: onInterrupt is a stable useCallback that calls interruptThreadTurn and surfaces failures via setThreadError. The global keydown handler runs thread.stop through that same path as the composer stop control.

Settings: The keybinding command picker seeds from STATIC_KEYBINDING_COMMANDS instead of only default resolved bindings, so unbound commands like thread.stop still appear for assignment.

Tests cover schema decoding, shortcut resolution, and command-option building.

Reviewed by Cursor Bugbot for commit 7ae0496. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 56deff9e-8b83-45f4-bf50-c63480305458

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Jul 22, 2026
@jakeleventhal
jakeleventhal marked this pull request as ready for review July 22, 2026 20:40

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 7ae0496. Configure here.

event.preventDefault();
event.stopPropagation();
void onInterrupt();
return;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stop shortcut ignores running state

Medium Severity

The new thread.stop keybinding unconditionally calls onInterrupt. Unlike the UI stop button, which is only active when a turn is running, this allows interrupting idle threads or drafts without an active server turn, which can lead to unexpected thread errors or interrupt failure messages.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 7ae0496. Configure here.

if (command === "thread.stop") {
event.preventDefault();
event.stopPropagation();
void onInterrupt();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Held stop key repeats interrupt

Low Severity

The thread.stop keydown branch does not ignore event.repeat, so holding the bound key can enqueue multiple onInterrupt calls. Other thread-related shortcuts in the sidebar explicitly bail out when event.repeat is true.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 7ae0496. Configure here.

@macroscopeapp

macroscopeapp Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR adds new user-facing keybinding functionality with unresolved review comments identifying potential bugs: the stop shortcut doesn't check if a thread is running before attempting interrupt, and doesn't handle key repeat events. These issues warrant human review.

You can customize Macroscope's approvability policy. Learn more.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7ae04963d6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +3949 to +3952
if (command === "thread.stop") {
event.preventDefault();
event.stopPropagation();
void onInterrupt();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Gate thread.stop to running turns

When a custom thread.stop shortcut is pressed on an active thread after its turn has settled, this block still calls onInterrupt() even though the provider session may only be ready. The server accepts thread.turn.interrupt for any non-stopped session and adapters such as OpenCode abort the session without requiring an active turn, while the existing Stop button is only exposed when phase === "running". Gate this shortcut on the same running/activeTurnId condition so pressing the binding on an idle thread is a no-op instead of aborting provider state.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M 30-99 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant